#!/usr/bin/env python2
#-*- coding: utf-8 -*-

import traceback

from Ump import utils
from Ump.common import log
from Ump.common import exception
from Ump.umptypes import UmpPath

from Ump.objs.db import models
from Ump.objs.session_wrapper import enable_log_and_session, _sw
from Ump.objs.manager_base import Manager

from Ump.lich.cgsnapshot import LichCGSnapshot, LichCGSnapshotParam


LOG = log.get_log('Ump.objs.vgroup.manager')


class VGroupManager(Manager):
    MODEL = models.VGroup

    def __init__(self):
        super(VGroupManager, self).__init__()
        self.lichCGSnapshot = LichCGSnapshot()

    def _check_double_name(self, user_id, name):
        vgroups = _sw.get_one(model=models.VGroup, id_or_spec={'user_id': user_id, 'name': name})
        if vgroups:
            raise Exception("指定的名称已被使用")
        
    @enable_log_and_session(resource='vgroup', event='create')
    def create(self, _logger, kwargs):
        path = kwargs['vgroup_name']

        _logger.set_obj(path)
        vgroup = self._create(**kwargs)
        return vgroup

    def _create(self, username='admin', volume_ids=None, **kwargs):
        """modify to create without volume.
        """
    # def _create(self, name, volume_ids, username='admin', **kwargs):

        user = _sw.get_user(username=username)
        if not user:
            raise exception.UserNotFound(username=username)

        vgroup_name = kwargs['vgroup_name']
        self._check_double_name(user.id, vgroup_name)

        volumes = _sw.get_list_by_ids(models.Volume, volume_ids)
        for volume in volumes:
            if volume.vgroup_id:
                raise exception.VGroupReferenced('卷已有卷组')
        values = {
            'user_id': user.id,
            'name': vgroup_name,
            'volumes': volumes,
        }
        vgroup = models.VGroup(values).save()
        return vgroup 

    @enable_log_and_session(resource='vgroup', event='delete')
    def delete(self, _logger, kwargs):
        if kwargs.get('id'):
            vgroup_id = kwargs.get('id')
            vgroup = self._get_one(vgroup_id)
        else:
            vgroup = _sw.get_vgroup(kwargs)

        if not vgroup:
            raise exception.NotFound(kwargs)

        _logger.set_obj(vgroup.name)
        
        self._check_before_delete(vgroup)

        vgroup.volumes = []
        vgroup.delete()
        return True

    def _check_before_delete(self, vgroup):
        if vgroup.cgsnapshots:
            raise exception.VGroupReferenced('卷组已有快照')

        return True

    @enable_log_and_session(resource='vgroup', event='update')
    def update(self, _logger, kwargs):
        path = kwargs['vgroup_name']

        _logger.set_obj(path)

        vgroup = self._update(**kwargs)
        return vgroup

    def _update(self, volume_ids=None, add_volume_list=None, remove_volume_list=None, **kwargs):
        vgroup_id = kwargs.get('id')
        name = kwargs.get('vgroup_name')
        username = kwargs.get('username')
        if vgroup_id:
            vgroup = models.VGroup.query.filter_by(id=vgroup_id).first()
        else:
            vgroup = _sw.get_vgroup(kwargs)
        self._check_before_delete(vgroup)
        values = dict()
        utils.update_values(values, 'name', name)

        volumes = vgroup.volumes
        add_volumes = []
        remove_volumes = []

        if add_volume_list:
            add_volume_list = add_volume_list.split(',')
            for volume in add_volume_list:
                volume_path = UmpPath(volume)
                add_volume = _sw.get_volume(volume_path)
                if add_volume.vgroup_id:
                    raise exception.VGroupReferenced('卷已有卷组')
                add_volumes.append(add_volume)
            volumes = volumes + add_volumes

        if remove_volume_list:
            remove_volume_list = remove_volume_list.split(',')
            for volume in remove_volume_list:
                volume_path = UmpPath(volume)
                remove_volume = _sw.get_volume(volume_path)
                remove_volumes.append(remove_volume)
            volumes = [vol for vol in volumes if vol not in remove_volumes]

        if volume_ids:
            volumes = _sw.get_list_by_ids(models.Volume, volume_ids)

        utils.update_values(values, 'volumes', volumes, is_list=True)

        vgroup.update(values)
        return vgroup 

    def _get_one(self, vgroup_id):
        vgroup = _sw.get_one(models.VGroup, id_or_spec=vgroup_id)
        if not vgroup:
            raise exception.NotFound(vgroup_id=vgroup_id)
        return vgroup

    @enable_log_and_session(resource='cgsnapshot', event='list', disable_oplog=True)
    def list_cgsnapshots(self, _logger, params):
        vgroup = _sw.get_vgroup(params)
        if not vgroup:
            raise exception.VolumeNotFound(params)

        return _sw.db_cgsnapshots({'vgroup_id': vgroup.id})


if __name__ == '__main__':
    snm = VGroupManager()
    snm.sync_vgroup()
